package br.com.serctam.session;



import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.Query;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.log.Log;
import org.jboss.seam.persistence.HibernateSessionProxy;

import br.com.serctam.entity.BoletoPdf;
import br.com.serctam.entity.Candidato;
import br.com.serctam.entity.Cargo;
import br.com.serctam.entity.Cidade;
import br.com.serctam.entity.NumeroPreInscrisao;

@Stateful
@Name("PreCadastroCandidato")
public class PreCadastroCandidatoBean implements PreCadastroCandidato
{

	//Campos auxiliares
	private Integer diaNascimento;
	private Integer mesNascimento;
	private Integer anoNascimento;
	
	@Logger private Log log;

    @In StatusMessages statusMessages;
    
    @In(required=true ) Candidato candidato;
    
    @In(create=true)
    private GeradorBoleto geradorBoleto;
    
    @In(create=true)
    @Out(required=false)
    private BoletoPdf boletoPdf; 

    @In(create=true)
    private ConcursoHome concursoHome;
    
    
    @RequestParameter
    private String idConcurso;
    
//    @Out(scope=ScopeType.CONVERSATION)
//    private Concurso concurso;
    
    @Out(scope=ScopeType.CONVERSATION)
    private List<Cargo> cargos;
    
    @PersistenceContext
    private EntityManager entityManager;
    
    @In
    private HibernateSessionProxy hibernateSession;
    
    @Factory("cargos")
    public void populaCargos(){
    	
//    	if( concurso==null || concurso.getId()==null){
//    		if( idConcurso != null ){
//    			concursoHome.setId(idConcurso);
//    			concurso = concursoHome.find();
//    		} else {
//    			statusMessages.add("Concurso nao especificado");
//    		}
//    	//} else if {
//    		
//    	}
    	
    	cargos = entityManager.createQuery(" select c from Cargo c where c.concurso.id =  " + idConcurso ).getResultList();
    }

    @Create
    public void init(){
    	//candidato = new Candidato();
    }
    
    @End(beforeRedirect=false)
    public void preCadastroCandidato() throws IllegalStateException
    {

    	//Trata status Pagamento inicialmente NPG
    	candidato.setStatusPagamento("APG");
    	
    	//Trata envio de email confirmando recebimento PG
    	candidato.setMailPgEnviado(Boolean.FALSE);
    	
    	
    	//Trata numero de dependentes
    	if(candidato.getQtFilho() == null){
    		candidato.setQtFilho(0);
    	}
    	
    	//Trata email
    	if (StringUtils.isEmpty(candidato.getEmail())) {
			candidato.setEmail("concursopmh@hotmail.com");
		}
    	
    	
    	//Trata data nascimento
		Date dNasc = new Date();
		dNasc = DateUtils.setDays(dNasc, 1);
		dNasc = DateUtils.setDays(dNasc, diaNascimento);
		dNasc = DateUtils.setYears(dNasc, anoNascimento);
		dNasc = DateUtils.setMonths(dNasc, mesNascimento);
		dNasc = DateUtils.setDays(dNasc, diaNascimento);
		candidato.setDataNascimento(dNasc);
		

    	
    	//Trata campo obrigatotio condicional
    	// - Campo obs se checkbox outros estiver marcado
//    	if(candidato.getOutros() && (candidato.getObs() == null || "".equals(candidato.getObs()))){
//    		statusMessages.add("Campo obrigatorio quando Necessidade Especiais Outro for selecionado");
//    		throw new IllegalStateException();
//    		
//    	}
    	
    	//Trata data inscricao
    	candidato.setDataInscricao(GregorianCalendar.getInstance().getTime());
    	
    	//Trata numero pre-inscrisao
    	String numeroPreInscrisao = montaNumeroPreInscrisao();
    	candidato.setNumeroPreInscricao(numeroPreInscrisao);

    	//Grava no Banco de Dados
    	Cidade c = entityManager.find(Cidade.class, candidato.getCidade().getId());
    	candidato.setCidade(c);
    	//entityManager.merge(candidato);
    	entityManager.persist(candidato);
    	
    	//Gerar Boleto
    	ByteArrayOutputStream boleto = geradorBoleto.gerarBoleto(false);
    	boletoPdf.setBoletopdf(boleto.toByteArray());
    	candidato.setBoletoPdf(boletoPdf);
    	//entityManager.merge(candidato);

    	
        
        //Notifica o sucesso da operacao
        statusMessages.add("#{messages.sucessoPreInscricao}");
        
    }
    
    private String montaNumeroPreInscrisao(){
    	
    	Integer proximoNumeroPreInscrisao = buscaProximoNumeroPreInscrisao();
    	String strProximoNumeroPreInscrisao = proximoNumeroPreInscrisao.toString();
    	strProximoNumeroPreInscrisao = StringUtils.leftPad(strProximoNumeroPreInscrisao, 4, '0');
    	String numeroPreInscricao = candidato.getCargo().getCodigo();
    	numeroPreInscricao+= strProximoNumeroPreInscrisao;
    	
    	atualizaProximoNumeroPreInscrisao(proximoNumeroPreInscrisao);
    	
    	return numeroPreInscricao;
    	
    }
    
    private Integer buscaProximoNumeroPreInscrisao(){
    	
    	Query query = hibernateSession.getNamedQuery("buscaUltimoNumeroPreInscrisao"); 
    	query.setLong("idCargo", candidato.getCargo().getId());
    	
    	Object oResult = query.uniqueResult();
    	
    	if(oResult == null){
    		return 1;
    	} else {
    		Integer ultimo = Integer.parseInt(oResult.toString());
    		ultimo++;
    		return ultimo;
    	}
    	
    }
    
    
    private void atualizaProximoNumeroPreInscrisao(Integer ultimoUtilizado){
    	
    	if(ultimoUtilizado == 1){
    		NumeroPreInscrisao npi = new NumeroPreInscrisao();
    		npi.setCargo(candidato.getCargo());
    		npi.setUltimoNumero(1);
    		entityManager.persist(npi);
    	} else {
    		Query query = hibernateSession.getNamedQuery("atualizaUltimoNumeroPreInscrisao"); 
    		query.setLong("idCargo", candidato.getCargo().getId());
    		query.setInteger("ultimo", ultimoUtilizado);
    		query.setLong("idCargo", candidato.getCargo().getId());
    		int qt = query.executeUpdate();
    		log.info("atualizaProximoNumeroPreInscrisao tuplas afetadas" + qt);
    		
    	}
    	
    	log.info("Numero pre-inscrisao atualizado para " + ultimoUtilizado);
    	
    }
    
    

    // add additional action methods

    public String getIdConcurso()
    {
        return idConcurso;
    }

    public void setIdConcurso(String idConcurso)
    {
        this.idConcurso = idConcurso;
    }

    @Destroy
    @Remove
    public void destroy() {}

	public Candidato getCandidato() {
		return candidato;
	}

	public void setCandidato(Candidato candidato) {
		this.candidato = candidato;
	}
	

	public Integer getDiaNascimento() {
		return diaNascimento;
	}

	public void setDiaNascimento(Integer diaNascimento) {
		this.diaNascimento = diaNascimento;
	}

	public Integer getMesNascimento() {
		return mesNascimento;
	}

	public void setMesNascimento(Integer mesNascimento) {
		this.mesNascimento = mesNascimento;
	}

	public Integer getAnoNascimento() {
		return anoNascimento;
	}

	public void setAnoNascimento(Integer anoNascimento) {
		this.anoNascimento = anoNascimento;
	}

	public static void main(String[] args) {
		
//		String cpf = "123.456.789-00";
//		String reg = "[0-9]{3}.[0-9]{3}.[0-9]{3}-[0-9]{2}";
//		
//		System.out.println(cpf.matches(reg));
//		
//		System.out.println("CPF: " + cpf.replaceAll("\\.", "").replaceAll("-", "") );
//		
//		for (int i = 1931; i < 1997; i++) {
//        	System.out.println("<f:selectItem itemValue=\""+i+"\"/>");
//
//		}
		
		Date dNasc = new Date(0);
		
		dNasc = DateUtils.setDays(dNasc, 1);
		dNasc = DateUtils.setDays(dNasc, 5);
		dNasc = DateUtils.setMonths(dNasc, 0);
		dNasc = DateUtils.setYears(dNasc, 1980);
		
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		System.out.println(sdf.format(dNasc));
		System.out.println(dNasc);
		
	}

}
